"""辅助功能函数模块，仅调用 core_utils.py 的核心函数。"""

import os
import pandas as pd
from tabulate import tabulate
from src.core_utils import (
    load_field_stats, load_and_filter_city, get_missing_and_unique_stats,
    get_mean_table, print_mean_table, get_box_stats, print_box_stats,
    anova_by_year, print_anova_results, ensure_dir, save_figure, pca_analysis
    , fill_mode, preprocess_city_df
)

def aux_des_workflow(config):
    """
    一站式辅助函数，调用 core_utils 完成 des.py 的主要分析流程。
    参数 config: dict，包含所有路径和字段设置。
    """
    # 数据加载与预处理
    field_stats = load_field_stats(config.get('json_path'))
    city_df = load_and_filter_city(config.get('csv_path'))
    if city_df is not None:
        city_df = preprocess_city_df(city_df)
    if city_df is None:
        return
    missing_rate, unique_counts = get_missing_and_unique_stats(city_df)
    print("\n【缺失率前10的字段及示例值】")
    top_missing = missing_rate.sort_values(ascending=False)[:10]
    for col in top_missing.index:
        example = field_stats.get(col, {}).get("示例值", [])
        print(f"{col}: 缺失率 {top_missing[col]:.2%}, 示例值: {example}")
    print("\n【唯一值极少（<=5）或极多（>1000）的字段】")
    for col in city_df.columns:
        n = unique_counts[col]
        if n <= 5 or n > 1000:
            print(f"{col}: 唯一值数量 {n}, 示例值: {field_stats.get(col, {}).get('示例值', [])}")

    # 描述性统计与可视化
    score_fields = config.get('score_fields')
    year_field = config.get('year_field')
    mean_table = get_mean_table(city_df, score_fields, year_field)
    print_mean_table(mean_table)
    years = sorted(mean_table.index)
    # 自动绘制雷达图并保存
    from plot import plot_radar_chart
    figures_dir = config.get('figures_dir', 'figures')
    ensure_dir(figures_dir)
    radar_path = os.path.join(figures_dir, '雷达图.png')
    font_family = config.get('plot', {}).get('font_family', 'Heiti TC')
    fig = plot_radar_chart(mean_table, score_fields, years, save_path=None, figsize=(4, 3), font_family=font_family)
    from src.core_utils import save_figure
    if fig is not None:
        save_figure(fig, '雷达图.png', figures_dir)
    box_stats = get_box_stats(city_df, score_fields, year_field)
    print_box_stats(box_stats)

    # 方差分析（ANOVA）
    anova_results = anova_by_year(city_df, score_fields, year_field)
    print_anova_results(anova_results)

    # 分组对比分析
    if "性别" in city_df.columns:
        print("\n【按性别分组的均值（各年份）】")
        group_table = city_df.groupby([year_field, "性别"])[score_fields].mean()
        print(tabulate(group_table, headers='keys', tablefmt='github', floatfmt=".2f"))
    if "出生队列分组" in city_df.columns:
        print("\n【cohort（出生队列分组）描述性统计】")
        cohort_field = "出生队列分组"
        cohort_mean = city_df.groupby(cohort_field)[score_fields].mean()
        print(tabulate(cohort_mean, headers='keys', tablefmt='github', floatfmt=".2f"))
    
    # 主成分分析（PCA）
    from src.core_utils import pca_analysis
    df_pca, loadings = pca_analysis(city_df, score_fields, year_field)

def run_netvar_analysis():
    """
    封装原 try.py 的主运行流程，便于 main.py 或其它脚本调用。
    """
    import time
    from tqdm import tqdm
    import pandas as pd
    import logging
    import os
    import yaml
    from matplotlib.font_manager import FontProperties
    from tabulate import tabulate
    import matplotlib.pyplot as plt
    from netcore import (
        stability_analysis,
        bootstrap_centrality,
        centrality_anova_by_year,
        compare_jaccard,
        compare_centrality_ks,
        calc_residuals,
        build_network,
        print_node_metrics,
        get_network_overall_metrics,
        print_network_overall_metrics,
        fill_mode,
        preprocess_city_df,
        residual_network_by_year
    )
    from plot import draw_network, plot_stability_analysis

    # 读取 config.yaml
    with open('config.yaml', 'r', encoding='utf-8') as f:
        config = yaml.safe_load(f)

    CSV_PATH = config.get('csv_path')
    FIELDS_CORE = list(config.get('core_name_map', {}).keys())
    CORE_NAME_MAP = config.get('core_name_map', {})
    CONTROL_VARS = config.get('control_vars')
    FIGURES_DIR = config.get('figures_dir', 'figures')
    THRESHOLD = config.get('threshold', 0.1)
    CH_FONT_NAME = config.get('ch_font', 'Heiti TC')
    ch_font = FontProperties(fname=None, family=CH_FONT_NAME)

    try:
        df = pd.read_csv(CSV_PATH, low_memory=False)
        logging.info(f"CSV文件 {CSV_PATH} 读取成功，数据量：{df.shape[0]} 行，{df.shape[1]} 列。")
    except Exception as e:
        logging.error(f"CSV文件读取失败：{e}")
        raise

    if "城乡" not in df.columns:
        logging.error("未找到城乡字段，无法筛选城市样本。")
        raise ValueError("未找到城乡字段")

    city_df = preprocess_city_df(df)
    logging.info(f"城市样本筛选后行数: {len(city_df)}")

    # 检查核心变量字段是否全部存在
    missing_fields = [field for field in FIELDS_CORE if field not in city_df.columns]
    if missing_fields:
        logging.warning(f"数据表缺少以下核心变量字段，无法分析：{missing_fields}")
        print(f"⚠️ 数据表缺少以下核心变量字段，无法分析：{missing_fields}")
        raise ValueError(f"缺少字段: {missing_fields}")

    # 独热编码区县
    if "区县" in city_df.columns:
        district_dummies = pd.get_dummies(city_df["区县"], prefix="区县")
        city_df = pd.concat([city_df, district_dummies], axis=1)
        control_vars = [v for v in CONTROL_VARS if v != "区县"] + list(district_dummies.columns)
    else:
        control_vars = CONTROL_VARS.copy()

    all_vars = list(set(FIELDS_CORE + control_vars))
    df_net = city_df[FIELDS_CORE + control_vars].copy()
    df_net = df_net.dropna(subset=FIELDS_CORE)
    df_net = fill_mode(df_net, control_vars)

    # 只绘制五个核心变量显著且相关系数绝对值大于阈值的网络图
    data = df_net[FIELDS_CORE].dropna()
    G = build_network(data, FIELDS_CORE, CORE_NAME_MAP, threshold=THRESHOLD)
    draw_network(G, title="核心变量网络图", save_path=f"{FIGURES_DIR}/核心变量网络图.png", ch_font=ch_font, edge_threshold=THRESHOLD)

    # 1. 计算每个核心变量的残差（控制所有控制变量）
    residuals = calc_residuals(df_net, FIELDS_CORE, control_vars)

    # 2. 用残差做网络分析
    G2 = build_network(residuals, FIELDS_CORE, CORE_NAME_MAP, threshold=0.1, pval_cut=0.05)
    net_img_path3 = os.path.join(FIGURES_DIR, "控制变量后核心变量显著相关网络图.png")
    draw_network(G2, "控制变量后核心变量显著相关网络", net_img_path3, ch_font, node_color='red')

    # 打印节点指标
    print_node_metrics(G, "核心变量显著相关网络")
    print_node_metrics(G2, "控制变量后核心变量显著相关网络")
    print_network_overall_metrics(G, "核心变量显著相关网络")
    print_network_overall_metrics(G2, "控制变量后核心变量显著相关网络")

    # 按年份绘制残差网络图
    fig_path = residual_network_by_year(df_net, FIELDS_CORE, control_vars, CORE_NAME_MAP, ch_font, FIGURES_DIR, threshold=0.1, pval_cut=0.05)

    # 在网络分析部分添加统计检验
    print("\n" + "="*30 + " 中心性指标统计检验 " + "="*30)
    print("\n【Bootstrap中心性指标置信区间(95%)】")
    ci_results = bootstrap_centrality(G2)
    print(tabulate(ci_results, headers='keys', tablefmt='grid'))

    centrality_anova_by_year(df_net, FIELDS_CORE, control_vars, CORE_NAME_MAP)

    print("\n" + "="*30 + " 网络稳定性分析 " + "="*30)
    stability_results = stability_analysis(data, FIELDS_CORE, CORE_NAME_MAP)
    print("\n【原始数据不同阈值下的网络特征】")
    print(tabulate(stability_results, headers='keys', tablefmt='grid', floatfmt='.3f'))

    residual_stability = stability_analysis(residuals, FIELDS_CORE, CORE_NAME_MAP)
    print("\n【控制变量后残差数据不同阈值下的网络特征】")
    print(tabulate(residual_stability, headers='keys', tablefmt='grid', floatfmt='.3f'))

    # 可视化稳定性分析结果
    metrics = ['网络密度', '平均度数', '连通分量数量']
    stability_fig_path = plot_stability_analysis(stability_results, residual_stability, metrics, ch_font, FIGURES_DIR)
    print(f"网络稳定性分析图已保存：{stability_fig_path}")

    return {
        'G': G,
        'G2': G2,
        'fig_path': fig_path,
        'stability_fig_path': stability_fig_path,
        'city_df': city_df,
    }

